<template>
  <div class="slide-bar">
    <div ref="stripEmpty" class="strip-empty">
      <div ref="stripFill" class="strip-fill" />
      <div ref="slideBlock" class="slide-block" @touchmove="touchmove" />
    </div>
    <div class="slide-scales">
      <div
        v-for="(scale, index) in scales"
        :key="scale"
        :style="{ width: index == scales.length - 1 ? 0 : 100 / (scales.length - 1) + '%' }"
      >
        <span class="scale-value">{{ scale }}</span>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  props: {
    value: {
      type: Number,
      default: 0
    },
    scales: {
      type: Array,
      default () {
        return []
      }
    }
  },
  data () {
    return {
      currentValue: this.value,
      scaleWidth: 0,
      offset: {}
    }
  },
  watch: {
    value (val) {
      this.currentValue = val
      let fillWidth = 0
      if (val < this.scales[0]) {
        fillWidth = 0
      } else if (val >= this.scales[this.scales.length - 1]) {
        fillWidth = this.offset.width
      } else {
        let index = 0

        for (let i = 0; i < this.scales.length; i++) {
          if (this.scales[i] > val) {
            index = i - 1
            break
          }
        }

        fillWidth = this.scaleWidth * index +
          this.scaleWidth * (val - this.scales[index]) / (this.scales[index + 1] - this.scales[index])
      }

      this.$refs.slideBlock.style.marginLeft = fillWidth - 10 + 'px'
      this.$refs.stripFill.style.width = fillWidth + 'px'
    }
  },
  mounted () {
    this.offset = this.$refs.stripEmpty.getBoundingClientRect()
    this.scaleWidth = this.offset.width / (this.scales.length - 1)
  },
  methods: {
    touchmove (event) {
      const element = event.targetTouches[0]
      let fillWidth = 0

      if (element.clientX < this.offset.left) {
        fillWidth = 0
      } else if (element.clientX > this.offset.right) {
        fillWidth = this.offset.right - this.offset.left
      } else {
        fillWidth = element.clientX - this.offset.left
      }

      const index = Math.floor(fillWidth / this.scaleWidth)

      if (index >= this.scales.length - 1) {
        this.currentValue = this.scales[this.scales.length - 1]
      } else {
        const diff = this.scales[index + 1] - this.scales[index]
        this.currentValue = Math.floor(this.scales[index] + diff * (fillWidth - this.scaleWidth * index) / this.scaleWidth)
      }

      this.$emit('input', this.currentValue)
    }
  }
}
</script>

<style lang="scss" scoped>
.slide-bar {
  width: 100%;
  margin: 10px 0;
  position: relative;

  .strip-empty {
    width: 100%;
    height: 7px;
    background: #f2f2f2;
    border-radius: 8px;

    .strip-fill {
      height: 7px;
      border-radius: 8px;
      width: 0;
      background: #337dff;
    }

    .slide-block {
      background: rgba(159,215,255,.33);
      border-radius: 15px;
      width: 20px;
      height: 20px;
      border: 2px solid #337dff;
      margin-top: -14px;
      margin-left: -10px;
      position: absolute;
      box-shadow: 0 0 3px 3px #daf3ff;
      z-index: 2;
    }
  }

  .slide-scales {
    width: 98%;
    height: 15px;
    margin: 0 auto;

    div {
      margin-top: 10px;
      float: left;
      font-size: 10px;
      color: #555;
      position: relative;

      .scale-value {
        display: block;
        width: 40px;
        margin-left: -20px;
        text-align: center;
        height: 20px;
        line-height: 20px;
      }
    }

    div::before {
      content: "";
      width: 0;
      height: 7px;
      border-left: 1px solid #d9d9d9;
      position: absolute;
      top: -10px;
    }
  }
}
</style>
